package com.taskmanager.dao;

import com.taskmanager.entity.TimeRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 计时记录数据访问层
 */
@Mapper
public interface TimerDao {
    
    /**
     * 插入计时记录
     * @param record 计时记录对象
     * @return 影响的行数
     */
    int insert(TimeRecord record);
    
    /**
     * 根据记录ID查询计时记录
     * @param recordId 记录ID
     * @return 计时记录对象
     */
    TimeRecord selectById(@Param("recordId") Long recordId);
    
    /**
     * 根据记录ID查询计时记录（包含任务和分类信息）
     * @param recordId 记录ID
     * @return 计时记录对象（含关联信息）
     */
    TimeRecord selectByIdWithDetails(@Param("recordId") Long recordId);
    
    /**
     * 查询用户当前运行中或暂停的计时器
     * @param userId 用户ID
     * @return 计时记录对象，如果没有则返回null
     */
    TimeRecord selectCurrentTimer(@Param("userId") Long userId);
    
    /**
     * 查询任务的计时记录列表
     * @param userId 用户ID
     * @param taskId 任务ID（可选）
     * @param startDate 开始日期（可选）
     * @param endDate 结束日期（可选）
     * @return 计时记录列表
     */
    List<TimeRecord> selectByConditions(
            @Param("userId") Long userId,
            @Param("taskId") Long taskId,
            @Param("startDate") LocalDate startDate,
            @Param("endDate") LocalDate endDate
    );
    
    /**
     * 更新计时记录
     * @param record 计时记录对象
     * @return 影响的行数
     */
    int update(TimeRecord record);
    
    /**
     * 更新计时记录状态
     * @param recordId 记录ID
     * @param status 新状态
     * @param duration 持续时长（秒）
     * @return 影响的行数
     */
    int updateStatus(
            @Param("recordId") Long recordId,
            @Param("status") String status,
            @Param("duration") Integer duration
    );
    
    /**
     * 更新计时记录的结束时间和持续时长
     * @param recordId 记录ID
     * @param endTime 结束时间
     * @param duration 持续时长（秒）
     * @return 影响的行数
     */
    int updateEndTimeAndDuration(
            @Param("recordId") Long recordId,
            @Param("endTime") LocalDateTime endTime,
            @Param("duration") Integer duration
    );
    
    /**
     * 删除计时记录
     * @param recordId 记录ID
     * @return 影响的行数
     */
    int deleteById(@Param("recordId") Long recordId);
    
    /**
     * 检查记录是否属于指定用户
     * @param recordId 记录ID
     * @param userId 用户ID
     * @return 是否属于该用户
     */
    boolean belongsToUser(@Param("recordId") Long recordId, @Param("userId") Long userId);
    
    /**
     * 统计用户今日总时长
     * @param userId 用户ID
     * @return 总时长（秒）
     */
    Integer sumTodayDuration(@Param("userId") Long userId);
    
    /**
     * 统计用户本周总时长
     * @param userId 用户ID
     * @return 总时长（秒）
     */
    Integer sumWeekDuration(@Param("userId") Long userId);
    
    /**
     * 统计用户本月总时长
     * @param userId 用户ID
     * @return 总时长（秒）
     */
    Integer sumMonthDuration(@Param("userId") Long userId);
    
    /**
     * 按分类统计时长
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return Map<分类名称, 时长秒数>
     */
    List<Map<String, Object>> sumDurationByCategory(
            @Param("userId") Long userId,
            @Param("startDate") LocalDate startDate,
            @Param("endDate") LocalDate endDate
    );
    
    /**
     * 按日期统计时长
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return List<Map<日期, 时长>>
     */
    List<Map<String, Object>> sumDurationByDate(
            @Param("userId") Long userId,
            @Param("startDate") LocalDate startDate,
            @Param("endDate") LocalDate endDate
    );
    
    /**
     * 计算任务的总计时时长
     * @param taskId 任务ID
     * @return 总时长（秒）
     */
    Integer sumTaskDuration(@Param("taskId") Long taskId);
    
    /**
     * 统计指定时间范围内的总时长
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 总时长（秒）
     */
    Integer sumTotalDuration(
            @Param("userId") Long userId,
            @Param("startDate") LocalDate startDate,
            @Param("endDate") LocalDate endDate
    );
    
    /**
     * 统计指定时间范围内的总次数
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 总次数
     */
    Integer countTotalSessions(
            @Param("userId") Long userId,
            @Param("startDate") LocalDate startDate,
            @Param("endDate") LocalDate endDate
    );
    
    /**
     * 统计指定时间范围内的活跃天数
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 活跃天数
     */
    Integer countActiveDays(
            @Param("userId") Long userId,
            @Param("startDate") LocalDate startDate,
            @Param("endDate") LocalDate endDate
    );
    
    /**
     * 获取当日统计数据
     * @param userId 用户ID
     * @return Map包含sessions和duration
     */
    Map<String, Object> getTodayStatistics(@Param("userId") Long userId);
    
    /**
     * 按分类统计详细信息（包含次数）
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 分类统计列表
     */
    List<Map<String, Object>> sumDurationByCategoryWithDetails(
            @Param("userId") Long userId,
            @Param("startDate") LocalDate startDate,
            @Param("endDate") LocalDate endDate
    );
    
    /**
     * 按日期统计详细信息（包含次数）
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 每日统计列表
     */
    List<Map<String, Object>> sumDurationByDateWithSessions(
            @Param("userId") Long userId,
            @Param("startDate") LocalDate startDate,
            @Param("endDate") LocalDate endDate
    );
}
